/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  							 combat_spell_cell_target.cpp

	$Header: /heroes4/combat_spell_cell_target.cpp $

	$NoKeywords: $

 ************************************************************************/
// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "combat_spell_cell_target.h"

#include "battlefield.h"
#include "can_cast.h"
#include "combat_creature.h"
#include "combat_object_model_cache.h"
#include "external_string.h"
#include "format_string.h"
#include "map_rect.h"
#include "replace_keywords.h"
#include "spell.h"
#include "spell_properties.h"
#include "stationary_combat_object.h"

// -------------------------------------------------------------------
// spell which targets a square rather than a creature
// -------------------------------------------------------------------
t_combat_spell_cell_target::t_combat_spell_cell_target( t_battlefield& battlefield, t_spell spell )
                          : t_combat_spell( battlefield, spell )
{
}

// -------------------------------------------------------------------
// spell which targets a square rather than a creature
// -------------------------------------------------------------------
t_combat_spell_cell_target::~t_combat_spell_cell_target()
{
	if (m_target_shadow && m_target_shadow->get_list_position()._Mynode() != NULL)
		m_battlefield.remove_object( m_target_shadow );
}

// -------------------------------------------------------------------
// spell which targets a square rather than a creature
// -------------------------------------------------------------------
bool t_combat_spell_cell_target::begin_casting()
{
	t_combat_object_model_cache cache;
	int							size;
	std::string					name;

	size = get_footprint_size();
	name = format_string( "target_shadow.%i", size );
	cache = get_combat_object_model_cache( name, m_battlefield.get_model_scale() );
	m_target_shadow = new t_stationary_combat_object( m_battlefield, cache );
	return true;
}

// -------------------------------------------------------------------
// spell which targets a square rather than a creature
// -------------------------------------------------------------------
bool t_combat_spell_cell_target::can_cast( t_screen_point const& point ) const
{
	t_map_point_2d map_point;

	if (!m_battlefield.cell_hit_test( point, map_point ))
		return false;
	if (!check_line_of_sight( *m_caster, m_spell, map_point, 0 ))
		return false;
	return can_cast_here( map_point, 0 );
}

// -------------------------------------------------------------------
// spell which targets a square rather than a creature
// -------------------------------------------------------------------
extern t_external_string const k_text_cast_spell;

t_mouse_window* t_combat_spell_cell_target::mouse_move( t_screen_point const& point,
									           std::string& help_text )
{
	t_map_point_2d			center;

	m_battlefield.select_target( 0 );
	if (!m_battlefield.cell_hit_test( point, center )
		|| !check_line_of_sight( *m_caster, m_spell, center, &help_text )
		|| !can_cast_here( center, &help_text))
	{
		m_battlefield.remove_object( m_target_shadow );
		return m_battlefield.get_blocked_cursor();
	}

	int			   size = get_footprint_size();
	int			   half_size = (size - 1) / 2;
	t_map_point_2d new_position = center - t_map_point_2d(half_size, half_size);

	if (m_target_shadow->get_list_position()._Mynode() == NULL)
	{
		m_battlefield.place_object( m_target_shadow, 
			                         new_position << k_battlefield_subcell_shift );
	}
	else if (new_position != m_target_shadow->get_cell_position())
	{
		m_battlefield.move_object( *m_target_shadow, 
			                        new_position << k_battlefield_subcell_shift );
	}

	help_text = replace_keywords( k_text_cast_spell, "%spell_name", 
		                          get_spell_name( m_spell ));
	return m_battlefield.get_spell_cursor();
}

// -------------------------------------------------------------------
// spell which targets a square rather than a creature
// -------------------------------------------------------------------
bool t_combat_spell_cell_target::left_click( t_screen_point const& point )
{
	t_map_point_2d			center;

	if (!m_battlefield.cell_hit_test( point, center )
		|| !check_line_of_sight( *m_caster, m_spell, center, 0 )
		|| !can_cast_here( center, 0 ))
		return false;
	m_target_square = center;
	m_battlefield.remove_object( m_target_shadow );
	m_battlefield.begin_spell( center );
	return true;
}

